#ifndef _lcthw_Hashmap_h
#define _lcthw_Hashmap_h

#include <lcthw/darray.h>
#include <stdint.h>

#define DEFAULT_NUMBER_OF_BUCKETS 100

typedef int (*Hashmap_compare)(void *a, void *b);   // function pointer for comparing keys
typedef uint32_t (*Hashmap_hash)(void *key);        // function pointer for generating hash

typedef struct Hashmap 
{
    DArray *buckets;        // pointer to DArray of buckets
    Hashmap_compare compare;    // function pointer for comparing keys
    Hashmap_hash hash;          // function pointer for generating hash
} Hashmap;

typedef struct HashmapNode 
{
    void *key;          // pointer to the key
    void *data;         // pointer to the data
    uint32_t hash;      // hash value of the key
} HashmapNode;

// Hashmap_traverse_cb: function pointer for traversing the hashmap
// node: pointer to the hashmap node
// Returns: int
typedef int (*Hashmap_traverse_cb)(HashmapNode *node); 

// Hashmap_create: Creates a new hashmap, returns a pointer to the hashmap.
// compare: function pointer for comparing keys
// hash: function pointer for generating hash
// Returns: pointer to the hashmap
Hashmap *Hashmap_create(Hashmap_compare compare, Hashmap_hash hash); 

// Hashmap_destroy: Destroys the hashmap
// map: pointer to the hashmap
// Returns: void
void Hashmap_destroy(Hashmap *map);

// Hashmap_set: Adds a key-value pair to the hashmap
// map: pointer to the hashmap
// key: pointer to the key
// data: pointer to the data
// Returns: int
int Hashmap_set(Hashmap *map, void *key, void *data);

// Hashmap_get: Returns the data associated with the key
// map: pointer to the hashmap
// key: pointer to the key
// Returns: pointer to the data
void *Hashmap_get(Hashmap *map, void *key);

// Hashmap_traverse: Traverses the hashmap
// map: pointer to the hashmap
// traverse_cb: function pointer for traversing the hashmap
// Returns: int
int Hashmap_traverse(Hashmap *map, Hashmap_traverse_cb traverse_cb);

// Hashmap_delete: Deletes the key-value pair from the hashmap
// map: pointer to the hashmap
// key: pointer to the key
// Returns: pointer to the data
void *Hashmap_delete(Hashmap *map, void *key);

#endif